<?php

namespace services\statistics;

use Yii;
use yii\web\HttpException;
use common\components\Service;
use common\models\base\Project;
use common\models\base\PatientDiseases;
use common\models\clinic\Clinic;
use common\models\marketing\CallbackStatus;
use common\models\member\Attr;
use common\models\member\Member;
use common\models\patient\AllocationRecord;
use common\helpers\ArrayHelper;
use common\models\base\Profession;
use common\models\patient\Callback;
use common\models\patient\User;
use common\models\statistics\CallbackReport;
use services\patient\UserService;
use services\patient\CallbackService;

/**
 * Class CallbackReportService
 * @package services\statistics
 */
class CallbackReportService extends Service
{
    /**
     * 根据ID查找信息
     *
     * @param int $id
     * @return CallbackReport|null
     */
    public function findById(int $id = 0): ?CallbackReport
    {
        return CallbackReport::findOne($id);
    }

    /**
     * 获取信息
     *
     * @param array $condition
     * @return CallbackReport|null
     */
    public function findInfo(array $condition = []): ?CallbackReport
    {
        $query = CallbackReport::find();

        isset($condition['menu_id']) && $query->andWhere(['menu_id' => $condition['menu_id']]);

        return $query->one();
    }


    /**
     * 获取列表
     *
     * @param array $condition
     * @return array|\yii\db\ActiveRecord[]
     */
    public function findList(array $condition = [])
    {
        $query = CallbackReport::find();

        isset($condition['id']) && $query->andWhere(['id' => $condition['id']]);
        isset($condition['status']) && $query->andWhere(['status' => $condition['status']]);

        return $query->asArray()->all();
    }

    /**
     * 统计报表列表
     *
     * @param array $params
     * @param int $page
     * @param int $pageSize
     * @return array
     */
    public function getListPage(array $params = [], int $page = 0, int $pageSize = 0)
    {
        $query = CallbackReport::find()->select(['*'])
            ->where(['project_id' => $params['project_id']]);
        if (isset($params['profession_id'])) {
            $query->andWhere(['profession_id' => $params['profession_id']]);
        }

        if (isset($params['start_time']) && $params['start_time']) {
            $query->andWhere(['>=', 'date', strtotime($params['start_time'])]);
        }

        if (isset($params['end_time']) && $params['end_time']) {
            $query->andWhere(['<=', 'date', strtotime($params['end_time'] . ' 23:59:59')]);
        }
        if (isset($params['check_member_id']) && $params['check_member_id']) {
            $query->andWhere(['in', 'callback_member_id', $params['check_member_id']]);
        }
        // 总数
        $total = $query->count();

        // 分页
        if ($page && $pageSize) {
            $query->limit($pageSize)->offset(($page - 1) * $pageSize);
        }

        $list = $query
            ->orderBy(['callback_member_id' => SORT_DESC])
            ->asArray()
            ->all();

        return [
            'page' => (int)$page,
            'pageSize' => (int)$pageSize,
            'total' => (int)$total,
            'list' => $list,
        ];
    }

    /**
     * 格式化列表
     *
     * @param array $data
     * @param int $projectId
     * @return array
     */
    public function getListPageFormat(array $data = [], array $condition = [])
    {
        $list = [];
        $total = [
            'callback_num' => 0,
            'callback_patient_num' => 0,
            'callback_way' => [],
            'callback_state' => [],
            'callback_year' => [],
        ];

        // 回访总人数
        $memberCallbackTotalList = Yii::$app->services->patientCallback->statisticsCallbackTotalNum([
            'member_id' => array_column($data, 'callback_member_id'),
            'project_id' => $condition['project_id'],
            'start_time' => $condition['start_time'],
            'end_time' => $condition['end_time'],
        ]);

        foreach ($memberCallbackTotalList as $row) {
            $total['callback_patient_num'] += $row['total_num'];
        }

        foreach ($data as $row) {
            $callbackWay = $row['callback_way'] ? json_decode($row['callback_way'], true) : [];
            $callbackState = $row['callback_state'] ? json_decode($row['callback_state'], true) : [];
            $callbackYear = $row['year'] ? json_decode($row['year'], true) : [];

            // 总数
            $row['callback_patient_num'] = $memberCallbackTotalList[$row['callback_member_id']]['total_num'] ?? 0;
            $total['callback_num'] += $row['callback_num'];

            // 回访方式格式化
            foreach ($condition['callback_way_list'] as $val) {
                $callbackWay[$val['id']] = $callbackWay[$val['id']] ?? 0;

                // 总数
                $total['callback_way'][$val['id']] = $total['callback_way'][$val['id']] ?? 0;
                $total['callback_way'][$val['id']] += $callbackWay[$val['id']];
            }
            // 回访状态格式化
            foreach ($condition['callback_status_list'] as $val) {
                $callbackState[$val['id']] = $callbackState[$val['id']] ?? 0;

                // 总数
                $total['callback_state'][$val['id']] = $total['callback_state'][$val['id']] ?? 0;
                $total['callback_state'][$val['id']] += $callbackState[$val['id']];
            }
            // 回访年份格式化
            foreach ($condition['year_list'] as $val) {
                $callbackYear[$val] = $callbackYear[$val] ?? 0;

                // 总数
                $total['callback_year'][$val] = $total['callback_year'][$val] ?? 0;
                $total['callback_year'][$val] += $callbackYear[$val];
            }

            $item = [
                // 'id' => $row['id'],
                // 'project_id' => $row['project_id'],
                // 'profession_id' => $row['profession_id'],
                'callback_member_id' => $row['callback_member_id'],
                'callback_member_name' => $row['callback_member_name'],
                'callback_num' => $row['callback_num'],
                'callback_patient_num' => $row['callback_patient_num'],
                'clinic_name' => $row['clinic_name'],
                'callback_way' => $callbackWay,
                'callback_state' => $callbackState,
                'callback_year' => $callbackYear,
            ];


            if (isset($list[$row['callback_member_id']])) {
                $list[$row['callback_member_id']]['callback_num'] += $item['callback_num'];
                // $list[$row['callback_member_id']]['callback_patient_num'] += $item['callback_patient_num'];
                // 回访方式
                foreach ($condition['callback_way_list'] as $val) {
                    $list[$row['callback_member_id']]['callback_way'][$val['id']] += $item['callback_way'][$val['id']];
                }
                // 回访状态
                foreach ($condition['callback_status_list'] as $val) {
                    $list[$row['callback_member_id']]['callback_state'][$val['id']] += $item['callback_state'][$val['id']];
                }
                // 回访年份
                foreach ($condition['year_list'] as $val) {
                    $list[$row['callback_member_id']]['callback_year'][$val] += $item['callback_year'][$val];
                }
            } else {
                $list[$row['callback_member_id']] = $item;
            }
        }

        return [
            'list' => array_values($list),
            'total' => $total,
        ];
    }

    /**
     * 回访统计报表【昨日数据】
     *
     * @param array $params
     * @return string
     */
    public function statistics(array $params = [])
    {
        set_time_limit(0);
        ini_set('memory_limit', '2G');

        // 统计回访数据【按照回访人分组】
        $query = Callback::find()->alias('a')
            ->select([
                'a.member_id',
                'a.member_name',
                'a.project_id',
                'GROUP_CONCAT(a.patient_user_id) AS patient_user_id',
                'GROUP_CONCAT(a.callback_state_id) AS callback_state_id',
                'GROUP_CONCAT(a.callback_way_id) AS callback_way_id',
                'GROUP_CONCAT(b.reg_time) AS reg_time',
            ])
            ->innerJoin(User::tableName() . ' AS b', 'b.id = a.patient_user_id')
            ->innerJoin(Attr::tableName() . ' AS c', 'c.member_id = a.member_id AND c.project_id=a.project_id')
            ->where([
                'a.status' => Callback::STATUS_ENABLE,
                'c.profession_id' => [Profession::ID_MEDICAL, Profession::ID_CUSTOMER]
            ])
            ->groupBy('a.member_id,a.project_id');

        // 开始时间
        $startTime = strtotime($params['date']);
        $query->andWhere(['>=', 'a.current_callback_time', $startTime]);

        // 结束时间
        $query->andWhere(['<=', 'a.current_callback_time', strtotime($params['date'] . ' 23:59:59')]);

        // 查询结果
        $data = $query->asArray()->all();

        // 归属人属性列表
        $memberIds = array_column($data, 'member_id');
        $attrList = Yii::$app->services->attr->findList([
            'member_id' => $memberIds,
        ]);
        $clinicList = Yii::$app->services->clinic->findList([
            'id' => array_column($attrList, 'clinic_id'),
            'indexBy' => 'id',
        ]);
        $attrListFormat = [];
        foreach ($attrList as $row) {
            $row['clinic_name'] = $clinicList[$row['clinic_id']]['name'] ?? '';
            $attrListFormat[$row['member_id']][$row['project_id']] = $row;
        }

        // 用户信息
        $columns = [
            'project_id',
            'profession_id',
            'callback_member_id',
            'callback_member_name',
            'callback_num',
            'callback_patient_num',
            'clinic_name',
            'callback_way',
            'callback_way_num',
            'callback_state',
            'callback_state_num',
            'year',
            'year_num',
            'date',
            'created_at',
        ];

        // 批量新增数据
        $insertData = [];
        // 统计日期
        $dateTimestamp = $startTime;
        foreach ($data as $row) {
            if (empty($row['member_id'])) {
                continue;
            }

            // 岗位ID
            $professionId = $attrListFormat[$row['member_id']][$row['project_id']]['profession_id'] ?? 0;

            // 回访患者IDs
            $patientUserIdArr = $row['patient_user_id'] ? explode(',', $row['patient_user_id']) : [];
            $callbackNum = count($patientUserIdArr);
            $callbackPatientNum = count(array_unique($patientUserIdArr));

            // 诊室
            $clinicName = $attrListFormat[$row['member_id']][$row['project_id']]['clinic_name'] ?? '';

            // 回访方式
            $callbackWayIdArr = $row['callback_way_id'] ? explode(',', $row['callback_way_id']) : [];
            $callbackWay = ArrayHelper::getElementNum($callbackWayIdArr);
            $callbackNumWay = [];
            foreach ($callbackWayIdArr as $k => $val) {
                $callbackNumWay[$val][$patientUserIdArr[$k]] = 1;
            }
            foreach ($callbackNumWay as $k => $val) {
                $callbackNumWay[$k] = count($val);
            }

            // 回访状态
            $callbackStateIdArr = $row['callback_state_id'] ? explode(',', $row['callback_state_id']) : [];
            $callbackState = ArrayHelper::getElementNum($callbackStateIdArr);
            $callbackNumState = [];
            foreach ($callbackStateIdArr as $k => $val) {
                $callbackNumState[$val][$patientUserIdArr[$k]] = 1;
            }
            foreach ($callbackNumState as $k => $val) {
                $callbackNumState[$k] = count($val);
            }

            // 回访年份【初诊年份-患者人数】
            $patientRegTimeArr = $row['reg_time'] ? explode(',', $row['reg_time']) : [];
            $yearArr = [];
            $yearNumArr = [];
            foreach ($patientRegTimeArr as $k => $val) {
                if (empty($val)) {
                    continue;
                }

                $date = date('Y', $val);
                $yearArr[$date] = $yearArr[$date] ?? 0;
                $yearArr[$date]++;

                $yearNumArr[$date][$patientUserIdArr[$k]] = 1;
            }
            $callbackYear = $yearArr;
            foreach ($yearNumArr as $k => $val) {
                $yearNumArr[$k] = count($val);
            }

            $insertData[] = [
                $row['project_id'],
                $professionId == Profession::ID_CUSTOMER ? CallbackReport::PROFESSION_ID_CUSTOMER : CallbackReport::PROFESSION_ID_MEDICAL,
                $row['member_id'],
                $row['member_name'],
                $callbackNum,
                $callbackPatientNum,
                $clinicName,
                $callbackWay,
                $callbackNumWay,
                $callbackState,
                $callbackNumState,
                $callbackYear,
                $yearNumArr,
                $dateTimestamp,
                Yii::$app->params['time'],
            ];
        }

        Yii::$app->db->createCommand()->batchInsert(
            CallbackReport::tableName(),
            $columns,
            $insertData
        )->execute();

        return 'success';
    }

    /**
     * 报表-经营-患者预览表
     *
     * @param int $project_id
     * @param array $params
     * @return array|\yii\db\ActiveRecord[]
     * @throws HttpException
     * @author chenyuebin
     */
    public function reportCallback(int $project_id, array $params)
    {
        if (!isset($params['profession_id']) || !$params['profession_id']) {
            throw new HttpException(422, '请选择岗位！');
        }
        if (isset($params['date_type']) && $params['date_type']) {
            $date = $this->getDateByType($params['date_type']);
        } else {
            $date = [
                'start_time' => strtotime(date("Y-m-d 00:00:00", strtotime($params['start_time']))),
                'end_time' => strtotime(date("Y-m-d 23:59:59", strtotime($params['end_time'])))
            ];
        }

        $diffMonth = self::get_month_diff($date['start_time'], $date['end_time']);
        if ($diffMonth > 3) {
            throw new HttpException(422, '时间最长不得超过3个月');
        }

        // 获取项目先对应客服/医助列表
        if (date("d") == 01 || date("d") == 15) {
            Yii::$app->redis->del('member_query_' . $params['profession_id'] . $project_id);
        }// 用来重置redis缓存的人员信息
        $memberQuery = Yii::$app->redis->get('member_query_' . $params['profession_id'] . $project_id);
        if ($memberQuery) {
            $memberList = json_decode($memberQuery, true);
        } else {
            $memberList = Attr::find()
                ->alias('a')
                ->leftJoin(Member::tableName() . ' m', 'a.member_id=m.id')
                ->leftJoin(Clinic::tableName() . ' c', 'a.clinic_id=c.id')
                ->select(['member_id', 'realname', 'clinic_id', 'c.name', 'c.sort'])
                ->where([
                    'and',
                    ['m.status' => Member::STATUS_ENABLE],
                    ['a.project_id' => $project_id],
                    ['profession_id' => $params['profession_id']],
                ])
                ->orderBy(['c.sort' => SORT_ASC])
                ->asArray()
                ->all();
            Yii::$app->redis->set('member_query_' . $params['profession_id'] . $project_id, json_encode($memberList), 'ex', 3600 * 24);
        }
        $memberIdList = [];
        foreach ($memberList as $value) {
            $memberIdList[] = $value['member_id'];
        }

        // 根据选择的医助还是客服来确认查询字段
        if ($params['profession_id'] == 301) {
            $memberType = 'u.belong_assistant_id';
            $memberTypeStr = 'belong_assistant_id';
        } else {
            $memberType = 'u.belong_member_id';
            $memberTypeStr = 'belong_member_id';
        }
        // 获取患者数据
        $patientQuery = Yii::$app->redis->get('report_query_' . $date['start_time'] . $date['end_time'] . $params['profession_id'] . $project_id);
        if ($patientQuery) {
            $query = json_decode($patientQuery, true);
        } else {
            $query = User::find()
                ->alias('u')
                ->leftJoin(PatientDiseases::tableName() . ' d', 'u.patient_diseases_id=d.id')
                ->leftJoin(Clinic::tableName() . ' clinic', 'u.clinic_id=clinic.id')
                ->select([
                    'last_revisiting_time',
                    'next_revisiting_time',
                    'd.diseases_name',
                    'clinic.name',
                    'u.clinic_id',
                    'u.id',
                    'u.patient_card_id',
                    'u.yz_next_callback_time',
                    'u.kf_next_callback_time',
                    'u.yz_next_callback_time',
                    'u.kf_next_callback_time',
                    'u.outpatient_type_id',
                    'u.belong_member_id',
                    'u.belong_assistant_id',
                ])
                ->where([
                    'and',
                    ['u.status' => User::STATUS_ENABLE],
                    ['u.project_id' => $project_id],
                    ['>', $memberType, 0],
                    [
                        'or',
                        ['<=', 'u.yz_next_callback_time', $date['end_time']],
                        ['<=', 'u.kf_next_callback_time', $date['end_time']],
                        ['<=', 'u.next_revisiting_time', $date['end_time']],
                        ['<=', 'u.last_revisiting_time', $date['end_time']],
                    ],
                ])
                ->orderBy(['clinic.sort' => SORT_ASC])
                ->asArray()
                ->all();
            Yii::$app->redis->set('report_query_' . $date['start_time'] . $date['end_time'] . $params['profession_id'] . $project_id, json_encode($query), 'ex', 60 * 1);
        }
        $temp_start_time = $date['start_time'];
        $temp_end_time = $date['end_time'];

        // 获取分配记录数据
        $patientAllocationQuery = Yii::$app->redis->get('patient_allocation_query_' . $temp_start_time . $temp_end_time . $params['profession_id'] . $project_id);
        if ($patientAllocationQuery) {
            $list = json_decode($patientAllocationQuery, true);
        } else {
            $current_profession_id = $params['profession_id'] == 301 ? 1 : 2;
            $list = AllocationRecord::find()
                ->select(['member_id', 'patient_card_id', 'created_at'])
                ->where([
                    'and',
                    ['project_id' => $project_id],
                    ['current_profession_id' => $current_profession_id],
                    ['>=', 'created_at', $temp_start_time],
                    ['<=', 'created_at', $temp_end_time],
                ])
                ->asArray()
                ->all();
            Yii::$app->redis->set('patient_allocation_query_' . $temp_end_time . $temp_end_time . $params['profession_id'] . $project_id, json_encode($list), 'ex', 60 * 1);
        }
        // 预到
        if (strtotime(date("Y-m-d 23:59:59")) <= $temp_end_time) {
            $date['start_time'] = strtotime(date("Y-m-d 00:00:00"));
        }
        $pre_arriva_ret = self::pub_data($query, $memberTypeStr, 'next_revisiting_time', $date['start_time'], $temp_end_time);

        // 过期未到
        if (strtotime(date("Y-m-d 00:00:00")) >= $temp_start_time) {
            $date['end_time'] = strtotime(date("Y-m-d 00:00:00"));
        }
        $un_arriva_ret = self::pub_data($query, $memberTypeStr, 'next_revisiting_time', $temp_start_time, $date['end_time'], 1);

        // 已回访
        $callbackList = Callback::find()
            ->select(['created_at', 'member_id', 'group_concat(patient_user_id) as id'])
            ->where([
                'and',
                ['project_id' => $project_id],
                ['status' => Callback::STATUS_ENABLE],
                ['>=', 'created_at', $temp_start_time],
                ['<=', 'created_at', $temp_end_time],
            ])
            ->groupBy(['member_id', 'patient_user_id'])
            ->asArray()
            ->all();
        // 过期未回访
        if ($params['profession_id'] == 301) {
            $last_callback_time_field = 'yz_next_callback_time';
        } else {
            $last_callback_time_field = 'kf_next_callback_time';
        }
        if (strtotime(date("Y-m-d 00:00:00")) >= $temp_start_time) {
            $date['end_time'] = strtotime(date("Y-m-d 00:00:00"));
        }
        $un_follow_ret = self::pub_data($query, $memberTypeStr, $last_callback_time_field, $temp_start_time, $date['end_time'], 1);

        // 复诊人数、新增人数
        $again_arriva_ret = [];
        $add_ret = [];
        $follow_ret = [];
        foreach ($query as $key => $value) {
            // 复诊人数
            $again_arriva_ret[$value[$memberTypeStr]]['diseases_name'] = $value['diseases_name'];
            $again_arriva_ret[$value[$memberTypeStr]]['name'] = $value['name'];
            $again_arriva_ret[$value[$memberTypeStr]]['clinic_id'] = $value['clinic_id'];
            $again_arriva_ret[$value[$memberTypeStr]][$memberTypeStr] = $value[$memberTypeStr];
            $again_arriva_ret[$value[$memberTypeStr]]['patient_id'] = [];
            $again_arriva_ret[$value[$memberTypeStr]]['count_patient'] = !isset($again_arriva_ret[$value[$memberTypeStr]]['count_patient']) ? 0 : $again_arriva_ret[$value[$memberTypeStr]]['count_patient'];
            if ($value['outpatient_type_id'] == Yii::$app->services->statisticsManagementReport::OUTPATIENT_TYPE['referral'] && $value['last_revisiting_time'] >= $temp_start_time && $value['last_revisiting_time'] <= $temp_end_time) {
                $again_arriva_ret[$value[$memberTypeStr]]['count_patient']++;
                $again_arriva_ret[$value[$memberTypeStr]]['patient_id'][] = $value['id'];
            }

            // 新增
            $add_ret[$value[$memberTypeStr]]['diseases_name'] = $value['diseases_name'];
            $add_ret[$value[$memberTypeStr]]['name'] = $value['name'];

            $add_ret[$value[$memberTypeStr]]['clinic_id'] = $value['clinic_id'];
            $add_ret[$value[$memberTypeStr]][$memberTypeStr] = $value[$memberTypeStr];
            $add_ret[$value[$memberTypeStr]]['count_patient'] = !isset($add_ret[$value[$memberTypeStr]]['count_patient']) ? 0 : $add_ret[$value[$memberTypeStr]]['count_patient'];
            $tempArr = [];
            $add_ret[$value[$memberTypeStr]]['patient_id'] = [];
            foreach ($list as $val) {
                if ($value['patient_card_id'] == $val['patient_card_id'] && $value[$memberTypeStr] == $val['member_id'] && $val['created_at'] >= $temp_start_time && $val['created_at'] <= $temp_end_time) {
                    $add_ret[$value[$memberTypeStr]]['patient_id'][] = $value['id'];
                    if (!in_array($val['patient_card_id'], $tempArr)) {
                        $tempArr[] = $val['patient_card_id'];
                        $add_ret[$value[$memberTypeStr]]['count_patient']++;
                    }
                }
            }

            // 已回访
            $follow_ret[$value[$memberTypeStr]]['diseases_name'] = $value['diseases_name'];
            $follow_ret[$value[$memberTypeStr]]['name'] = $value['name'];
            $follow_ret[$value[$memberTypeStr]]['clinic_id'] = $value['clinic_id'];
            $follow_ret[$value[$memberTypeStr]][$memberTypeStr] = $value[$memberTypeStr];
            $follow_ret[$value[$memberTypeStr]]['member_id'] = $value[$memberTypeStr];
            $follow_ret[$value[$memberTypeStr]]['patient_id'] = [];
            $follow_ret[$value[$memberTypeStr]]['count_patient'] = !isset($follow_ret[$value[$memberTypeStr]]['count_patient']) ? 0 : $follow_ret[$value[$memberTypeStr]]['count_patient'];
        }

        $data = [];
        foreach ($memberList as $key => $value) {
            $data[$key] = [
                'add_num' => 0,
                'add_id' => isset($add_ret[$value['member_id']]) ? implode(',', $add_ret[$value['member_id']]['patient_id']) : '',
                'add_num_type' => 1,
                'pre_num' => 0,
                'pre_id' => isset($pre_arriva_ret[$value['member_id']]) ? implode(',', $pre_arriva_ret[$value['member_id']]['patient_id']) : '',
                'pre_num_type' => 2,
                'pass_num' => 0,
                'pass_id' => isset($un_arriva_ret[$value['member_id']]) ? implode(',', $un_arriva_ret[$value['member_id']]['patient_id']) : '',
                'pass_num_type' => 3,
                'achieve_callback_num' => 0,
                'achieve_callback_patien_id' => '',
                'achieve_callback_num_type' => 4,
                'no_callback_num' => 0,
                'no_callback_id' => isset($un_follow_ret[$value['member_id']]) ? implode(',', $un_follow_ret[$value['member_id']]['patient_id']) : '',
                'no_callback_num_type' => 5,
                'revisiting_num' => 0,
                'revisiting_id' => isset($again_arriva_ret[$value['member_id']]) ? implode(',', $again_arriva_ret[$value['member_id']]['patient_id']) : '',
                'revisiting_num_type' => 6,

                'member_id' => $value['member_id'],
                'mmeber_name' => $value['realname'],
                'clinic_id' => $value['clinic_id'],
                'clinic_name' => $value['name'],
                'profession_id' => $params['profession_id'],
                'project_id' => $project_id,
                'end_time' => $temp_end_time,
                'start_time' => $temp_start_time,
                'sort' => isset($value['sort']) ? $value['sort'] : '',
            ];
            $data[$key]['add_num'] = self::setData($add_ret, $value, $memberTypeStr);
            $data[$key]['pre_num'] = self::setData($pre_arriva_ret, $value, $memberTypeStr);
            $data[$key]['pass_num'] = self::setData($un_arriva_ret, $value, $memberTypeStr);
//            $data[$key]['achieve_callback_num'] = self::setData($follow_ret, $value, 'member_id');
            $data[$key]['no_callback_num'] = self::setData($un_follow_ret, $value, $memberTypeStr);
            $data[$key]['revisiting_num'] = self::setData($again_arriva_ret, $value, $memberTypeStr);
            foreach ($callbackList as $val) {
                if ($value['member_id'] == $val['member_id']) {
                    $data[$key]['achieve_callback_num']++;
                    $data[$key]['achieve_callback_patien_id'] .= $val['id'] . ',';
                }
            }
        }

        return $data;
    }

    /**
     * 换取公共参数
     * @param array $data
     * @param int $member_id
     * @param int $start_time
     * @param int $end_time
     * @return mixed
     * @author chenyuebin
     */
    public static function pub_data(array $all, string $member_id, string $filed, int $start_time = 0, int $end_time = 0, int $data_cate = 0)
    {
        $tempArr = [];
        foreach ($all as $key => $value) {
            $tempArr[$value[$member_id]]['diseases_name'] = $value['diseases_name'];
            $tempArr[$value[$member_id]]['name'] = $value['name'];
            $tempArr[$value[$member_id]]['clinic_id'] = $value['clinic_id'];
            $tempArr[$value[$member_id]][$member_id] = $value[$member_id];
            $tempArr[$value[$member_id]]['count_patient'] = !isset($tempArr[$value[$member_id]]['count_patient']) ? 0 : $tempArr[$value[$member_id]]['count_patient'];
            $tempArr[$value[$member_id]]['patient_id'] = isset($tempArr[$value[$member_id]]['patient_id']) ? $tempArr[$value[$member_id]]['patient_id'] : [];
            if ($data_cate == 1) {// 等于1代表过期未。。。所以不能包含今天
                if ($value[$filed] >= $start_time && $value[$filed] < $end_time) {
                    $tempArr[$value[$member_id]]['count_patient']++;
                    $tempArr[$value[$member_id]]['patient_id'][] = $value['id'];
                }
            } else {
                if ($value[$filed] >= $start_time && $value[$filed] <= $end_time) {
                    $tempArr[$value[$member_id]]['count_patient']++;
                    $tempArr[$value[$member_id]]['patient_id'][] = $value['id'];
                }
            }
        }
        return $tempArr;
    }

    /**
     * 两个时间相差的月份
     * @param $start
     * @param bool $end
     * @return float|int
     * @author chenyuebin
     */
    public static function get_month_diff($start, $end = FALSE)
    {
        $end OR $end = time();
        $start = new \DateTime("@$start");
        $end = new \DateTime("@$end");
        $diff = $start->diff($end);
        return $diff->format('%y') * 12 + $diff->format('%m');
    }

    /**
     * 返回对应数量
     *
     * @param array $allData
     * @param array $childData
     * @param string $memberTypeStr
     * @return int|mixed
     * @author chenyuebin
     */
    public static function setData(array $allData, array $childData, string $memberTypeStr)
    {
        $num = 0;
        foreach ($allData as $k => $v) {
            if ($v[$memberTypeStr] == $childData['member_id']) {
                $num = isset($v['count_patient']) ? $v['count_patient'] : 0;
            }
        }
        return $num;
    }

    /**
     * 经营-预览列表-详情列表
     *
     * @param array $params
     * @param int $page
     * @param int $pageSize
     * @return array|\yii\db\ActiveRecord[]
     * @author chenyuebin
     */
    public function reportCallbackInfo(array $params, int $page, int $pageSize)
    {
        $data_type = $params['data_type'];
        $query = User::find()
            ->alias('u');
        if ($data_type == 4 || $data_type == 5) {
            $query->leftJoin(Callback::tableName() . ' c', 'c.patient_user_id=u.id');
        }
        $query->leftJoin(PatientDiseases::tableName() . ' d', 'u.patient_diseases_id=d.id');
        if ($data_type == 1) {
            $query->leftJoin(AllocationRecord::tableName() . ' a', 'a.patient_card_id=u.patient_card_id');
        }
        $query->select([
            'u.patient_card_id',
            'name',
            'age',
            'gender',
            'reg_time',
            'last_revisiting_time',
            'missed_days',
            'next_revisiting_time',
            'yz_callback_count',
            'kf_callback_count',
            'd.diseases_name',
            'u.id',
            'u.belong_assistant_id',
            'u.belong_member_id',
        ]);
        if ($data_type == 4 || $data_type == 5) {
            $query->addSelect('count(c.id) count_follow');
        }
        $query->where([
            'and',
            ['u.status' => User::STATUS_ENABLE],
            ['u.project_id' => $params['project_id']],
        ]);

        // 如果有顾问信息
        if (isset($params['member_id']) && $params['member_id'] && $data_type != 4) {
            if ($data_type == 1) { // 新增统计
                if ($params['profession_id'] == 301) { // 医助
                    $query->andWhere([
                        'a.member_id' => $params['member_id'],
                        'a.current_profession_id' => 1
                    ]);
                    $query->andWhere('`u`.`belong_assistant_id` = a.member_id');
                } else {
                    $query->andWhere([
                        '`a`.`member_id`' => $params['member_id'],
                        'a.current_profession_id' => 2
                    ]);
                    $query->andWhere('`u`.`belong_member_id` = a.member_id');
                }
            } else {
                if ($params['profession_id'] == 301) {
                    $query->andWhere([
                        'u.belong_assistant_id' => $params['member_id']
                    ]);
                } else {
                    $query->andWhere([
                        'u.belong_member_id' => $params['member_id']
                    ]);
                }
            }
        }
        $temp_start_time = strtotime($params['start_time'] . ' 00:00:00');
        $temp_end_time = strtotime($params['end_time'] . ' 23:59:59');
        switch ($data_type) {
            case 1: // 新增统计
                $query->andWhere([
                    'and',
                    ['>=', 'a.created_at', $temp_start_time],
                    ['<=', 'a.created_at', $temp_end_time]
                ])
                    ->groupBy('u.id');
                break;
            case 2:// 预到
                if (strtotime(date("Y-m-d 23:59:59")) <= $temp_end_time) {
                    $params['start_time'] = strtotime(date("Y-m-d 00:00:00"));
                }
                $query->andWhere([
                    'and',
                    ['>=', 'next_revisiting_time', $params['start_time']],
                    ['<=', 'next_revisiting_time', $temp_end_time]
                ])
                    ->groupBy('u.id');
                break;
            case 3:// 过期未到
                if (strtotime(date("Y-m-d 00:00:00")) >= $temp_start_time) {
                    $params['end_time'] = strtotime(date("Y-m-d 00:00:00"));
                }
                $query->andWhere([
                    'and',
                    ['>=', 'next_revisiting_time', $temp_start_time],
                    ['<', 'next_revisiting_time', $params['end_time']]
                ])
                    ->groupBy('u.id');
                //$query->andWhere(['<', 'next_revisiting_time', $params['end_time']])

                break;
            case 4:// 已回访
                /*if ($params['profession_id'] == 301) {
                    $last_callback_time_field = 'u.yz_last_callback_time';
                } else {
                    $last_callback_time_field = 'u.kf_last_callback_time';
                }
                $query->andWhere([
                    'and',
                    ['>=', $last_callback_time_field, $temp_start_time],
                    ['<=', $last_callback_time_field, $temp_end_time]
                ]);*/
                $query->andWhere([
                    'and',
                    ['>=', 'c.created_at', $temp_start_time],
                    ['<=', 'c.created_at', $temp_end_time],
                    ['c.member_id' => $params['member_id']]
                ])
                    ->groupBy('c.patient_user_id');
                break;
            case 5:// 过期未回访
                if ($params['profession_id'] == 301) {
                    $last_callback_time_field = 'u.yz_next_callback_time';
                } else {
                    $last_callback_time_field = 'u.kf_next_callback_time';
                }
                if (strtotime(date("Y-m-d 00:00:00")) >= $temp_start_time) {
                    $params['end_time'] = strtotime(date("Y-m-d 00:00:00"));
                }
                $query->andWhere([
                    'and',
                    ['>=', $last_callback_time_field, $temp_start_time],
                    ['<', $last_callback_time_field, $params['end_time']]
                ])
                    ->groupBy('u.id');
                //$query->andWhere(['<', $last_callback_time_field, $params['end_time']]);

                break;
            case 6:// 复诊人数
                $query->andWhere([
                    'and',
                    ['>=', 'u.last_revisiting_time', $temp_start_time],
                    ['<=', 'u.last_revisiting_time', $temp_end_time],
                    ['u.outpatient_type_id' => Yii::$app->services->statisticsManagementReport::OUTPATIENT_TYPE['referral']]
                ])
                    ->groupBy('u.id');
                break;
        }
        // 总数
        $total = $query->count();

        // 分页
        if ($page && $pageSize) {
            $query->limit($pageSize)->offset(($page - 1) * $pageSize);
        }
        $data = $query->asArray()->all();
        if ($data) {
            foreach ($data as $key => $value) {
                $data[$key]['gender'] = User::$genders[$value['gender']];
                $data[$key]['callback_count'] = $value['yz_callback_count'] + $value['kf_callback_count'];
                $data[$key]['reg_time'] = $value['reg_time'] ? date("Y-m-d", $value['reg_time']) : '';
                $data[$key]['last_revisiting_time'] = $value['last_revisiting_time'] ? date("Y-m-d", $value['last_revisiting_time']) : '';
                $data[$key]['next_revisiting_time'] = $value['next_revisiting_time'] ? date("Y-m-d", $value['next_revisiting_time']) : '';
                $data[$key]['callback_count_month'] = $this->callbackMonth($value['id']);
            }
        }

        return [
            'page' => (int)$page,
            'pageSize' => (int)$pageSize,
            'total' => (int)$total,
            'list' => $data,
        ];
    }

    /**
     * 根据患者id获取本月回访次数
     *
     * @param int $patient_id
     * @return int
     * @author chenyuebin
     */
    public function callbackMonth(int $patient_id)
    {
        $userService = new UserService();
        $date = $userService->getChooseTime('month', 2);
        $count_callback = Callback::find()
            ->select(['count(id) count'])
            ->where([
                'and',
                ['status' => Callback::STATUS_ENABLE],
                ['patient_user_id' => $patient_id],
                ['>=', 'created_at', $date['start_time']],
                ['<=', 'created_at', $date['end_time']],
            ])
            ->scalar();
        return (int)$count_callback;
    }

    /**
     * 置换具体日期
     *
     * @param int $date_type
     * @return array
     * @author chenyuebin
     */
    public function getDateByType(int $date_type)
    {
        $userService = new UserService();
        switch ($date_type) {
            case 1:
                $date = $userService->getChooseTime('day', 1);
                break;
            case 2:
                $date = $userService->getChooseTime('week', 1);
                break;
            case 3:
                $date = $userService->getChooseTime('month', 1);
                break;
            default:
                $date = $userService->getChooseTime('day', 1);
                break;
        }
        return $date;
    }

    /**
     * 回访报表【实时统计】
     *
     * @param array $params
     * [
     *      'project_id' => 0,// 项目ID
     *      'profession_id' => 1,// 类型【1客服、2医助】
     *      'start_time' => '2020-01-01',// 开始时间
     *      'end_time' => '2020-01-01',// 结束时间
     * ]
     * @return array
     */
    public function getTimeReportCallbackList(array $params)
    {
        // 属性
        $attr = Yii::$app->services->attr->findInfo([
            'member_id' => Yii::$app->user->identity->member_id,
            'project_id' => $params['project_id'],
        ]);
        // 获取要查询的归属人id
        if ($attr && $attr->is_department_leader == Attr::IS_DEPARTMENT_LEADER_NO) {
            $params['check_member_id'] = [Yii::$app->user->identity->member_id];
        } elseif ($attr && $attr->is_department_leader == Attr::IS_DEPARTMENT_LEADER_YES) {
            $params['check_member_id'] = Yii::$app->services->attr->findMemberId(['project_id' => $params['project_id'], 'department_id' => $attr->department_id]);
        }

        // 统计回访数据【按照回访人分组】
        $query = Callback::find()->alias('a')
            ->select([
                'a.member_id',
                'a.member_name',
                'a.project_id',
                'COUNT(a.patient_user_id) AS callback_num',
                'COUNT(DISTINCT a.patient_user_id) AS callback_patient_num',
            ])
            ->innerJoin(User::tableName() . ' AS b', 'b.id = a.patient_user_id')
            ->innerJoin(Attr::tableName() . ' AS c', 'c.member_id = a.member_id AND c.project_id=a.project_id')
            ->where([
                'a.project_id' => $params['project_id'],
                'a.status' => Callback::STATUS_ENABLE,
            ])
            ->indexBy('member_id')
            ->groupBy('a.member_id');

        // 类型
        if ($params['profession_id'] == 1) {
            $query->andWhere(['c.profession_id' => Profession::ID_CUSTOMER]);
        } elseif ($params['profession_id'] == 2) {
            $query->andWhere(['c.profession_id' => Profession::ID_MEDICAL]);
        }

        // 开始时间
        if ($params['start_time']) {
            $query->andWhere(['>=', 'a.current_callback_time', strtotime($params['start_time'])]);
        }

        // 结束时间
        if ($params['end_time']) {
            $query->andWhere(['<=', 'a.current_callback_time', strtotime($params['end_time'] . ' 23:59:59')]);
        }

        if (isset($params['check_member_id']) && $params['check_member_id']) {
            $query->andWhere(['a.member_id' => $params['check_member_id']]);
        }
        $data = $query->asArray()->all();

        // 统计【回访方式、回访状态、数据年份】
        $query = Callback::find()->alias('a')
            ->select([
                'a.member_id',
                'a.project_id',
                'a.patient_user_id',
                'a.callback_state_id',
                'a.callback_way_id',
                'b.reg_time',
            ])
            ->innerJoin(User::tableName() . ' AS b', 'b.id = a.patient_user_id')
            ->innerJoin(Attr::tableName() . ' AS c', 'c.member_id = a.member_id AND c.project_id=a.project_id')
            ->where([
                'a.project_id' => $params['project_id'],
                'a.status' => Callback::STATUS_ENABLE,
            ]);

        // 类型
        if ($params['profession_id'] == 1) {
            $query->andWhere(['c.profession_id' => Profession::ID_CUSTOMER]);
        } elseif ($params['profession_id'] == 2) {
            $query->andWhere(['c.profession_id' => Profession::ID_MEDICAL]);
        }

        // 开始时间
        if ($params['start_time']) {
            $query->andWhere(['>=', 'a.current_callback_time', strtotime($params['start_time'])]);
        }

        // 结束时间
        if ($params['end_time']) {
            $query->andWhere(['<=', 'a.current_callback_time', strtotime($params['end_time'] . ' 23:59:59')]);
        }

        if (isset($params['check_member_id']) && $params['check_member_id']) {
            $query->andWhere(['a.member_id' => $params['check_member_id']]);
        }
        $dataList = $query->asArray()->all();

        $total = [
            'callback_num' => 0,
            'callback_patient_num' => 0,
            'callback_way' => [],
            'callback_state' => [],// 人次
            'callback_year' => [],
        ];

        // 格式化
        foreach ($dataList as $row) {
            $year = $row['reg_time'] ? date('Y', $row['reg_time']) : '';

            // 回访方式
            $data[$row['member_id']]['callback_way'][$row['callback_way_id']] = $data[$row['member_id']]['callback_way'][$row['callback_way_id']] ?? 0;
            // 回访状态
            $data[$row['member_id']]['callback_state'][$row['callback_state_id']] = $data[$row['member_id']]['callback_state'][$row['callback_state_id']] ?? 0;
            // 数据年份
            $data[$row['member_id']]['callback_year'][$year] = $data[$row['member_id']]['callback_year'][$year] ?? 0;
            // 回访人数
            $data[$row['member_id']]['patient_callback_state'][$row['callback_state_id']][$row['patient_user_id']] = 1;

            $data[$row['member_id']]['callback_way'][$row['callback_way_id']] += 1;
            $data[$row['member_id']]['callback_state'][$row['callback_state_id']] += 1;
            $data[$row['member_id']]['callback_year'][$year] += 1;

            $total['callback_way'][$row['callback_way_id']] = $total['callback_way'][$row['callback_way_id']] ?? 0;
            $total['callback_state'][$row['callback_state_id']] = $total['callback_state'][$row['callback_state_id']] ?? 0;
            $total['callback_year'][$year] = $total['callback_year'][$year] ?? 0;

            $total['callback_way'][$row['callback_way_id']] += 1;
            $total['callback_state'][$row['callback_state_id']] += 1;
            $total['callback_year'][$year] += 1;
        }

        // 回访方式
        $callbackWayIds = Callback::$callbackWayIds;
        $callbackWayIdsStr = [];
        foreach ($callbackWayIds as $key => $row) {
            $callbackWayIdsStr[] = [
                'id' => $key,
                'name' => $row,
            ];
        }

        // 回访状态
        $condition = Yii::$app->services->patientUser->getConditionList(['get_callback_status' => 1]);

        // 统计时间
        $userYear = Yii::$app->services->patientUser->getUserRegTimeYearList([
            'project_id' => $params['project_id'],
        ]);

        // 条件
        $condition = [
            'callback_way_list' => $callbackWayIdsStr,
            'callback_status_list' => $condition['callback_status_list'],
            'year_list' => array_column($userYear, 'year'),
        ];

        $professionId = $attr ? $attr->profession_id : 0;
        $professionType = 0;

        // 返回客服还是医助的列表
        $profession_list = [
            [
                'id' => 2,
                'profession_name' => '医助'
            ],
            [
                'id' => 1,
                'profession_name' => '客服'
            ]
        ];
        if ($professionId == Profession::ID_MEDICAL) {// 医助
            $professionType = 2;
            $profession_list = [
                [
                    'id' => $professionType,
                    'profession_name' => '医助'
                ]
            ];
        } elseif ($professionId == Profession::ID_CUSTOMER) {// 客服
            $professionType = 1;
            $profession_list = [
                [
                    'id' => $professionType,
                    'profession_name' => '客服'
                ]
            ];
        }

        // 归属人属性列表
        $memberIds = array_column($data, 'member_id');
        $attrList = Yii::$app->services->attr->findList([
            'member_id' => $memberIds,
            'project_id' => $params['project_id'],
        ]);
        $clinicList = Yii::$app->services->clinic->findList([
            'id' => array_column($attrList, 'clinic_id'),
            'indexBy' => 'id',
        ]);
        $attrListFormat = [];
        foreach ($attrList as $row) {
            $row['clinic_name'] = $clinicList[$row['clinic_id']]['name'] ?? '';
            $row['clinic_sort'] = $clinicList[$row['clinic_id']]['sort'] ?? '';
            $attrListFormat[$row['member_id']] = $row;
        }

        // 格式化
        foreach ($data as $key => $row) {
            $total['callback_num'] += $row['callback_num'];
            $total['callback_patient_num'] += $row['callback_patient_num'];

            // 诊室
            $data[$key]['clinic_name'] = $attrListFormat[$row['member_id']]['clinic_name'] ?? '';
            $data[$key]['clinic_id'] = $attrListFormat[$row['member_id']]['clinic_id'] ?? 0;
            $data[$key]['clinic_sort'] = $attrListFormat[$row['member_id']]['clinic_sort'] ?? 0;

            foreach ($condition['callback_way_list'] as $v) {
                $data[$key]['callback_way'][$v['id']] = $data[$key]['callback_way'][$v['id']] ?? 0;
            }

            foreach ($condition['callback_status_list'] as $v) {
                $data[$key]['callback_state'][$v['id']] = $data[$key]['callback_state'][$v['id']] ?? 0;
                $data[$key]['patient_callback_state'][$v['id']] = isset($data[$key]['patient_callback_state'][$v['id']]) ? count($data[$key]['patient_callback_state'][$v['id']]) : 0;
            }

            foreach ($condition['year_list'] as $v) {
                $data[$key]['callback_year'][$v] = $data[$key]['callback_year'][$v] ?? 0;
            }

            $normalCallbackNum =  intval($data[$key]['patient_callback_state'][CallbackStatus::ID_NORMAL] ?? 0);
            $data[$key]['normal_callback_rate'] = round($normalCallbackNum / $data[$key]['callback_patient_num'] * 100, 0) ;
        }
        foreach ($condition['callback_way_list'] as $v) {
            $total['callback_way'][$v['id']] = $total['callback_way'][$v['id']] ?? 0;
        }
        foreach ($condition['callback_status_list'] as $v) {
            $total['callback_state'][$v['id']] = $total['callback_state'][$v['id']] ?? 0;
        }
        foreach ($condition['year_list'] as $v) {
            $total['callback_year'][$v] = $total['callback_year'][$v] ?? 0;
        }

        array_multisort(
            array_column($data, 'clinic_sort'), SORT_ASC,
            array_column($data, 'clinic_id'), SORT_ASC,
            array_column($data, 'member_id'), SORT_ASC,
            $data
        );

        return [
            'profession_type' => $professionType,
            'list' => array_values($data),
            'total' => $total,
            'condition' => $condition,
            'profession_list' => $profession_list
        ];
    }

    /**
     * 获取报表信息
     *
     * @param array $params
     * @return array
     */
    public function getReportInfo(array $params)
    {
        // 属性
        $attr = Yii::$app->services->attr->findInfo([
            'member_id' => Yii::$app->user->identity->member_id,
            'project_id' => $params['project_id'],
        ]);

        $professionId = $attr ? $attr->profession_id : 0;
        $professionType = 0;

        // 返回客服还是医助的列表
        $profession_list = [
            [
                'id' => 2,
                'profession_name' => '医助'
            ],
            [
                'id' => 1,
                'profession_name' => '客服'
            ]
        ];
        if ($professionId == Profession::ID_MEDICAL) {// 医助
            $professionType = 2;
            $profession_list = [
                [
                    'id' => $professionType,
                    'profession_name' => '医助'
                ]
            ];
        } elseif ($professionId == Profession::ID_CUSTOMER) {// 客服
            $professionType = 1;
            $profession_list = [
                [
                    'id' => $professionType,
                    'profession_name' => '客服'
                ]
            ];
        }

        return [
            'profession_type' => $professionType,
            'profession_list' => $profession_list
        ];
    }

    /**
     * 回访报表【静态统计】
     *
     * @param array $params
     * [
     *      'profession_id' => 1,// 类型【1客服、2医助】
     *      'start_time' => '2020-01-01',// 开始时间
     *      'end_time' => '2020-01-01',// 结束时间
     * ]
     * @return array
     */
    public function getStaticsReportCallbackList(array $params)
    {
        // 回访方式
        $callbackWayIds = Callback::$callbackWayIds;
        $callbackWayIdsStr = [];
        foreach ($callbackWayIds as $key => $row) {
            $callbackWayIdsStr[] = [
                'id' => $key,
                'name' => $row,
            ];
        }

        // 回访状态
        $condition = Yii::$app->services->patientUser->getConditionList(['get_callback_status' => 1]);

        // 统计时间
        $userYear = Yii::$app->services->patientUser->getUserRegTimeYearList();

        // 条件
        $condition = [
            'callback_way_list' => $callbackWayIdsStr,
            'callback_status_list' => $condition['callback_status_list'],
            'year_list' => array_column($userYear, 'year'),
        ];

        $select = [
            'a.project_id', 'a.profession_id',
            'SUM(a.callback_num) AS callback_num',
            'SUM(a.callback_patient_num) AS callback_patient_num',
//            'b.name AS pname',
        ];
        foreach ($condition['callback_way_list'] as $key => $row) {
            $select[] = "SUM(callback_way->'$.\"{$row['id']}\"') AS callback_way_{$row['id']}";
            //$select[] = "SUM(callback_way_num->'$.\"{$row['id']}\"') AS callback_way_num_{$row['id']}";
        }
        foreach ($condition['callback_status_list'] as $key => $row) {
            $select[] = "SUM(callback_state->'$.\"{$row['id']}\"') AS callback_state_{$row['id']}";
            $select[] = "SUM(callback_state_num->'$.\"{$row['id']}\"') AS callback_state_num_{$row['id']}";
        }
        foreach ($condition['year_list'] as $row) {
            $select[] = "SUM(year->'$.\"{$row}\"') AS year_{$row}";
        }

        // 查询结果
        $query = CallbackReport::find()->alias('a')
            ->select($select)
//            ->innerJoin(Project::tableName().' AS b', 'b.id = a.project_id')
            ->groupBy('a.project_id');
        if (isset($params['profession_id'])) {
            $query->andWhere(['a.profession_id' => $params['profession_id']]);
        }

        $nowTime = strtotime(date('Y-m-d'));
        $starTime = '';
        $endTime = '';
        if (isset($params['start_time']) && $params['start_time']) {
            $query->andWhere(['>=', 'a.date', strtotime($params['start_time'])]);

            $starTime = strtotime($params['start_time']) >= $nowTime ? date('Y-m-d', $nowTime-86400) : $params['start_time'];
        }

        if (isset($params['end_time']) && $params['end_time']) {
            $query->andWhere(['<=', 'a.date', strtotime($params['end_time'] . ' 23:59:59')]);

            $endTime = strtotime($params['end_time']) >= $nowTime ? date('Y-m-d', $nowTime-86400) : $params['end_time'];
        } else {
            $endTime = date('Y-m-d', $nowTime-86400);
        }

        $data = $query->asArray()->all();

        $projectList = Project::find()
            ->where([
                'id' => array_column($data, 'project_id')
            ])
            ->asArray()
            ->indexBy('id')
            ->all();

        // 总数
        $total = [
            'callback_num' => 0,
            'callback_patient_num' => 0,
            'callback_way' => [],
            'callback_state' => [],// 人次
            'callback_year' => [],
        ];

        $callbackService = new CallbackService();

        $dataFormat = [];
        foreach ($data as $row) {
            $item = [
                'project_id' => $row['project_id'],
                'profession_id' => $row['profession_id'],
//                'pname' => $row['pname'],
                'pname' => $projectList[$row['project_id']]['name'] ?? '',
                'callback_num' => $row['callback_num'],
                'callback_patient_num' => $row['callback_patient_num'],
                'normal_callback_rate' => 0,
                'callback_way' => [],
                //'callback_way_num' => [],
                'callback_state' => [],
                'callback_state_num' => [],
                'callback_year' => [],
            ];

            // 实时统计总人数
            $callbackData = $callbackService->getReportMemberListPage([
                'project_id' => $row['project_id'],
                'profession_id' => $row['profession_id'],
                'start_time' => $starTime,
                'end_time' => $endTime,
            ], 1, 10, 1);
            $item['callback_patient_num'] = $callbackData['total'];

            foreach ($condition['callback_way_list'] as $k => $v) {
                $item['callback_way'][$v['id']] = isset($row["callback_way_{$v['id']}"]) ? $row["callback_way_{$v['id']}"] : 0;
                //$item['callback_way_num'][$v['id']] = isset($row["callback_way_num_{$v['id']}"]) ? $row["callback_way_num_{$v['id']}"] : 0;

                $total['callback_way'][$v['id']] = $total['callback_way'][$v['id']] ?? 0;
                $total['callback_way'][$v['id']] += $item['callback_way'][$v['id']];
            }
            foreach ($condition['callback_status_list'] as $k => $v) {
                $item['callback_state'][$v['id']] = isset($row["callback_state_{$v['id']}"]) ? $row["callback_state_{$v['id']}"] : 0;
                $item['callback_state_num'][$v['id']] = isset($row["callback_state_num_{$v['id']}"]) ? $row["callback_state_num_{$v['id']}"] : 0;

                $total['callback_state'][$v['id']] = $total['callback_state'][$v['id']] ?? 0;
                $total['callback_state'][$v['id']] += $item['callback_state'][$v['id']];
            }
            foreach ($condition['year_list'] as $v) {
                $item['callback_year'][$v] = isset($row["year_{$v}"]) ? $row["year_{$v}"] : 0;

                $total['callback_year'][$v] = $total['callback_year'][$v] ?? 0;
                $total['callback_year'][$v] += $item['callback_year'][$v];
            }


            // 正常回访人数
            $callbackNormalData = $callbackService->getReportMemberListPage([
                'project_id' => $row['project_id'],
                'profession_id' => $row['profession_id'],
                'start_time' => $starTime,
                'end_time' => $endTime,
                'callback_state_id' => CallbackStatus::ID_NORMAL,
            ], 1, 10, 1);
            $normalNum = $callbackNormalData['total'];

            // 正常回访比率
//            $normalId = CallbackStatus::ID_NORMAL;
//            $normalNum = $row["callback_state_num_{$normalId}"] ?? 0;
            $item['normal_callback_rate'] = round($normalNum / $item['callback_patient_num'] * 100, 0);
            unset($item['callback_state_num']);
            $dataFormat[] = $item;

            $total['callback_num'] += $item['callback_num'];
            $total['callback_patient_num'] += $item['callback_patient_num'];
        }

        // 项目列表
        $projectList = Project::find()
            ->where(['not in', 'id', array_column($dataFormat, 'project_id')])
            ->andWhere(['status' => [Project::STATUS_INVALID, Project::STATUS_ENABLE]])
            ->asArray()
            ->all();
        foreach ($projectList as $row) {
             $item = [
                'project_id' => $row['id'],
                'profession_id' => $params['profession_id'],
                'pname' => $row['name'],
                'callback_num' => 0,
                'callback_patient_num' => 0,
                'normal_callback_rate' => 0,
                'callback_way' => [],
                //'callback_way_num' => [],
                'callback_state' => [],
                'callback_state_num' => [],
                'callback_year' => [],
            ];

            foreach ($condition['callback_way_list'] as $k => $v) {
                $item['callback_way'][$v['id']] = 0;
            }
            foreach ($condition['callback_status_list'] as $k => $v) {
                $item['callback_state'][$v['id']] = 0;
                $item['callback_state_num'][$v['id']] = 0;
            }
            foreach ($condition['year_list'] as $v) {
                $item['callback_year'][$v] = 0;
            }

            $dataFormat[] = $item;
        }
        $last_names = array_column($dataFormat, 'project_id');
        array_multisort($last_names, SORT_ASC, $dataFormat);

        // 属性
        $attr = Yii::$app->services->attr->findInfo([
            'member_id' => Yii::$app->user->identity->member_id,
            'project_id' => $params['project_id'],
        ]);
        $professionId = $attr ? $attr->profession_id : 0;
        $professionType = 0;

        // 返回客服还是医助的列表
        $profession_list = [
            [
                'id' => 2,
                'profession_name' => '医助'
            ],
            [
                'id' => 1,
                'profession_name' => '客服'
            ]
        ];
        if ($professionId == Profession::ID_MEDICAL) {// 医助
            $professionType = 2;
            $profession_list = [
                [
                    'id' => $professionType,
                    'profession_name' => '医助'
                ]
            ];
        } elseif ($professionId == Profession::ID_CUSTOMER) {// 客服
            $professionType = 1;
            $profession_list = [
                [
                    'id' => $professionType,
                    'profession_name' => '客服'
                ]
            ];
        }

        return [
            'profession_type' => $professionType,
            'list' => $dataFormat,
            'total' => $total,
            'condition' => $condition,
            'profession_list' => $profession_list
        ];
    }
}
